<template>
  <div class="table-container">
    <div class="right">
      <div class="header">
        <search-bar
          key="users"
          v-model="queryParams"
          :config="searchColumn"
          @search="handleSearch"
          @searchReset="handleReset"
        />
        <el-button v-hasPermi="['system.menu.add']" class="m_96" type="primary" @click="handleUserDialog">
          新增
        </el-button>
      </div>

      <el-table
        v-if="refreshTable"
        v-loading="loading"
        :data="tableData"
        row-key="menuId"
        :default-expand-all="isExpandAll"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      >
        <el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160" />
        <el-table-column label="类型" width="160">
          <template slot-scope="scope">
            <span>{{ menuTypeText(scope.row.menuType) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="belongSystem" label="所属系统" width="160">
          <template slot-scope="scope">
            <span>{{ systemText(scope.row.belongSystem) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="icon" label="图标" align="center" width="100">
          <template slot-scope="scope">
            <svg-icon :icon-class="scope.row.icon" />
          </template>
        </el-table-column>
        <el-table-column prop="orderNum" label="排序" />
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <span>{{ statusText(scope.row.status) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="left" prop="createTime">
          <!-- <template slot-scope="scope">
            <span>{{ parseTime(scope.row.createTime) }}</span>
          </template> -->
        </el-table-column>
        <el-table-column label="操作" align="left" class-name="small-padding fixed-width">
          <template slot-scope="scope">
            <el-button
              v-hasPermi="['system.menu.edit']"
              size="mini"
              type="text"
              style="color: #0076ff"
              @click="handleUpdate(scope.row)"
              >编辑</el-button
            >

            <el-button
              v-hasPermi="['system.menu.remove']"
              size="mini"
              type="text"
              style="color: #f37272"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>

      <!-- 新增/编辑 -->
      <el-dialog
        width="700px"
        class="app-dialog"
        :title="`${userDialogType}菜单`"
        :visible.sync="userDialogVisible"
        :before-close="handleUserDialogClose"
        :close-on-click-modal="false"
      >
        <div class="container">
          <div v-show="activeTab === 'basicInfo'">
            <el-form ref="userEdit" :model="userDialogData" :rules="rules">
              <!-- 所属系统 -->
              <el-form-item label="所属系统" prop="belongSystem" :disabled="isEditMode">
                <el-select
                  v-model="userDialogData.belongSystem"
                  :disabled="isEditMode"
                  placeholder="请选择所属系统"
                  @change="fetchTreeselectOptions"
                >
                  <el-option
                    v-for="option in systemOptions"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                  />
                </el-select>
              </el-form-item>

              <!-- 类型 -->
              <el-form-item label="类型" prop="menuType">
                <el-radio-group v-model="userDialogData.menuType" :disabled="isEditMode">
                  <el-radio label="M">目录</el-radio>
                  <el-radio label="C">菜单</el-radio>
                  <el-radio label="F">按钮</el-radio>
                </el-radio-group>
              </el-form-item>

              <!-- 上级菜单 -->
              <el-form-item label="上级目录" prop="parentId">
                <treeselect
                  v-model="userDialogData.parentId"
                  :options="menuOptions"
                  placeholder="选择上级目录"
                  :normalizer="normalizer"
                />
              </el-form-item>

              <!-- 名称 -->
              <el-form-item label="名称" prop="menuName">
                <el-input v-model="userDialogData.menuName" placeholder="请输入菜单名称" />
              </el-form-item>

              <!-- 图标 -->
              <el-form-item label="图标" prop="icon">
                <el-upload
                  :action="uploadAction"
                  :headers="uploadHeaders"
                  list-type="picture-card"
                  :file-list="fileList"
                  :limit="1"
                  :auto-upload="true"
                  :on-change="handleChange"
                  :on-exceed="handleExceed"
                  :on-success="handleUploadSuccess"
                >
                  <i slot="default" class="el-icon-plus" />
                  <div slot="file" slot-scope="{ file }">
                    <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
                    <span class="el-upload-list__item-actions">
                      <!-- <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                        <i class="el-icon-zoom-in" />
                      </span> -->
                      <span v-if="!iconDisabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
                        <i class="el-icon-delete" />
                      </span>
                    </span>
                  </div>
                </el-upload>
                <!-- <el-upload
                  :action="uploadAction"
                  :headers="uploadHeaders"
                  :limit="1"
                  :file-list="fileList"
                  :on-success="handleUploadSuccess"
                  :before-upload="handleBeforeUpload"
                >
                  <el-button slot="trigger" size="small" type="primary">上传图标</el-button>
                  <div slot="tip" class="el-upload__tip">只支持png/jpeg，大小不超过2MB</div>
                </el-upload> -->
              </el-form-item>

              <!-- 显示排序 -->
              <el-form-item label="显示排序" prop="orderNum">
                <el-input v-model="userDialogData.orderNum" type="number" placeholder="请输入数字，数字越小越靠前" />
              </el-form-item>

              <!-- 是否外链 -->
              <el-form-item label="是否外链" prop="isFrame">
                <el-radio-group v-model="userDialogData.isFrame">
                  <el-radio label="0">是</el-radio>
                  <el-radio label="1">否</el-radio>
                </el-radio-group>
              </el-form-item>

              <!-- 路由地址 -->
              <el-form-item label="路由地址" prop="path">
                <el-input v-model="userDialogData.path" placeholder="请输入路由地址" />
              </el-form-item>

              <!-- 权限字符 -->
              <el-form-item label="权限字符" prop="perms">
                <el-input v-model="userDialogData.perms" placeholder="请输入权限字符" :disabled="isMenuTypeDirectory" />
              </el-form-item>

              <!-- 显示状态 -->
              <el-form-item label="显示状态" prop="visible">
                <el-radio-group v-model="userDialogData.visible">
                  <el-radio label="0">显示</el-radio>
                  <el-radio label="1">隐藏</el-radio>
                </el-radio-group>
              </el-form-item>

              <!-- 状态 -->
              <el-form-item label="状态" prop="status">
                <el-radio-group v-model="userDialogData.status">
                  <el-radio label="0">生效</el-radio>
                  <el-radio label="1">失效</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-form>
          </div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button class="button" @click="handleUserDialogClose">取 消</el-button>
          <el-button class="button" type="primary" @click="handleUserSubmit">确 定</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import SearchBar from '@/components/SearchBar'
import { handleTree } from '@/utils/ruoyi'
import {
  listMenu,
  addMenu,
  updateMenu,
  getMenu,
  delMenu,
  roleMenuTreeselect,
  treeselect
} from '@/api/SystemSetting/accounts'
import { getNewToken } from '@/utils/auth'
export default {
  name: 'UserSearchTable',
  components: {
    Treeselect,
    SearchBar
  },
  data() {
    return {
      uploadAction: `${process.env.VUE_APP_BASE_API}/system/oss/upload`,
      uploadHeaders: { Authorization: 'Bearer ' + getNewToken() },
      iconDisabled: false,
      dialogImageUrl: '', // 用于预览图片的 URL
      dialogVisible: false, // 控制图片预览对话框的显示
      isEditMode: false,
      uploadList: [],
      fileList: [],
      tableData: [],
      loading: false,
      isExpandAll: false,
      refreshTable: true,
      activeTab: 'basicInfo',
      roleOptions: [],
      menuOptions: [],
      checkedKeys: [],
      queryParams: {},
      selectValue: [],
      deptTree: [],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      systemOptions: [
        { label: 'CRM', value: '0' },
        { label: '劳保', value: '1' },
        { label: '融合中台', value: '2' }
      ],
      rules: {
        menuName: [
          { required: true, message: '请输入菜单名称', trigger: 'blur' },
          { max: 30, message: '菜单名称不能超过30个字符', trigger: 'blur' }
        ],
        belongSystem: [{ required: true, message: '请选择所属系统', trigger: 'change' }],
        menuType: [{ required: true, message: '请选择类型', trigger: 'change' }]
      },
      isFetchingRole: false,
      isFetchingMenu: false,
      filterRole(query, item) {
        if (!item || !item.label) {
          return false
        }
        return item.label.toLowerCase().indexOf(query.toLowerCase()) > -1
      },
      searchColumn: [
        { prop: 'menuName', type: 'input', placeholder: '请输入菜单名称' },
        {
          prop: 'status',
          type: 'select',
          placeholder: '菜单状态',
          options: [
            { label: '生效', value: '0' },
            { label: '失效', value: '1' },
            { label: '休眠', value: '2' }
          ]
        },
        {
          prop: 'belongSystem',
          type: 'select',
          placeholder: '所属系统',
          options: [
            { label: 'CRM', value: '0' },
            { label: '劳保', value: '1' },
            { label: '融合中台', value: '2' }
          ]
        },
        {
          prop: 'search',
          type: 'button',
          policy: ['system.menu.query']
        }
      ],

      userDialogType: '',
      userDialogVisible: false,
      userDialogData: {
        parentId: null,
        menuId: undefined,
        menuName: undefined,
        icon: undefined,
        imageUrl: undefined,
        menuType: 'M',
        orderNum: '',
        isFrame: '1',
        isCache: '0',
        visible: '0',
        status: '0',
        perms: '' // 权限标识
      },

      authDialogVisible: false,
      pages: {
        total: 0,
        pageNum: 1,
        pageSize: 10
      }
    }
  },
  computed: {
    isMenuTypeDirectory() {
      return this.userDialogData.menuType === 'M'
    },
    menuTypeText() {
      return (menuType) => {
        switch (menuType) {
          case 'M':
            return '目录'
          case 'C':
            return '菜单'
          case 'F':
            return '按钮'
          default:
            return ''
        }
      }
    },
    systemText() {
      return (belongSystem) => {
        switch (belongSystem) {
          case '0':
            return 'CRM'
          case '1':
            return '劳保'
          case '2':
            return '融合中台'
          default:
            return ''
        }
      }
    },
    statusText() {
      return (status) => {
        switch (status) {
          case '0':
            return '生效'
          case '1':
            return '失效'
          default:
            return '未知状态'
        }
      }
    }
  },
  watch: {
    'userDialogData.belongSystem'(newVal) {
      if (newVal) {
        this.fetchTreeselectOptions(newVal) // Pass the selected system to the function
      }
    }
  },
  async mounted() {
    this.$bus.$off('handleEdit')
    this.$bus.$off('handleAuth')
    this.$bus.$off('handleDelete')
    // 编辑
    this.$bus.$on('handleEdit', async (rows) => {
      try {
        this.userDialogType = '编辑'
        this.userDialogVisible = true
        const response = await roleMenuTreeselect(rows.roleId)
        const role = response.data

        this.userDialogData = {
          roleName: rows.roleName,
          belongSystem: rows.belongSystem,
          status: rows.status,
          deptIds: rows.deptIds,
          menuIds: rows.menuIds,
          deptCheckStrictly: rows.deptCheckStrictly,
          menuCheckStrictly: rows.menuCheckStrictly
        }

        // 更新表单验证状态
        this.selectValue = role.checkedKeys
        // 获取系统对应的菜单
        await this.getMenuTree(rows.belongSystem)
        this.setPsdUsername()
      } catch (error) {
        this.$message.error('获取菜单信息失败，请稍后再试！')
      }
    })
    // 删除
    this.$bus.$on('handleDelete', (rows) => {
      this.$confirm(`删除数据，该项数据下的子项将同步删除，确认删除？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delMenu(rows.roleId).then((res) => {
          if (this.pages.total % this.pages.pageSize === 1) {
            const lastpage = (this.pages.total + this.pages.pageSize - 1) / this.pages.pageSize
            if (this.pages.pageNum == lastpage) {
              this.pages.pageNum = this.pages.pageNum - 1
            }
          }
          this.getTableData()
          this.$message({ type: 'success', message: '删除菜单成功!' })
        })
      })
    })
  },
  created() {
    this.getTableData()
  },
  beforeDestroy() {
    this.$bus.$off('handleEdit')
    this.$bus.$off('handleAuth')
    this.$bus.$off('handleDelete')
  },
  methods: {
    treeselect,
    getNewToken,
    handleBeforeUpload(file) {
      const isImage = file.type === 'image/png' || file.type === 'image/jpeg'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isImage) {
        this.$message.error('上传的文件格式必须是 PNG 或 JPEG!')
      }
      if (!isLt2M) {
        this.$message.error('上传的文件大小不能超过 2MB!')
      }
      return isImage && isLt2M
    },

    handleUploadSuccess(res, file) {
      if (res.code === 200) {
        this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId })
        this.userDialogData.icon = res.data.ossId
        this.userDialogData.imageUrl = res.data.url
        this.fileList.push({ name: res.data.fileName, url: res.data.url })
      } else {
        this.$message.error(res.msg)
      }
    },
    handleSearch() {
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleReset() {
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleSizeChange(v) {
      this.pages.pageSize = v
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleCurrentChange(v) {
      this.pages.pageNum = v
      this.getTableData()
    },
    handleUserDialog() {
      this.userDialogType = '新增'
      this.userDialogVisible = true
      this.isEditMode = false
      if (this.$refs.userEdit) {
        this.$refs.userEdit.resetFields()
      }
      // 确保字段不再被禁用
      // this.userDialogConfig = this.userDialogConfig.map((config) => {
      //   if (config.prop === 'belongSystem' || config.prop === 'menuType') {
      //     return { ...config, itemReadonly: false } // 解除禁用状态
      //   }
      //   return config
      // })
      // 只初始化必要的字段
      this.userDialogData = {
        parentId: null,
        belongSystem: '',
        menuType: 'C',
        menuName: '',
        icon: '',
        imageUrl: '',
        orderNum: '',
        isFrame: '1',
        path: '',
        visible: '0',
        status: '0'
      }
      this.roleOptions = []
      this.fileList = []
      // this.userDialogData.parentId = []
      this.setPsdUsername()
      // this.fetchTreeselectOptions()
    },
    handleUserDialogClose() {
      if (this.$refs.userEdit) {
        this.$refs.userEdit.resetFields()
      }
      this.menuOptions = []
      this.userDialogVisible = false
    },
    setPsdUsername() {
      // const rule = [
      //   { required: true, trigger: 'change', message: '请输入密码' },
      //   { required: true, validator: this.passwordValid, trigger: 'change' }
      // ]
      // const $id = this.userDialogData.id
      // const psd = this.userDialogConfig.find((i) => i.prop == 'password')
      // const rName = this.userDialogConfig.find((i) => i.prop == 'roleName')
      // this.$set(rName, 'disabled', !!$id)
      // this.$set(psd, 'rules', !$id ? rule : [])
    },
    handleAuthDialogClose() {},
    handleUpdate(row) {
      this.userDialogType = '编辑'
      this.userDialogVisible = true
      this.fetchTreeselectOptions()
      getMenu(row.menuId).then((response) => {
        const menu = response.data

        this.userDialogData = {
          ...menu,
          parentId: menu.parentId || null,
          belongSystem: menu.belongSystem, // 保留所属系统
          menuType: menu.menuType // 保留类型
        }
        this.fileList = [{ name: menu.icon, url: menu.imageUrl }]
        this.isEditMode = true
        if (!menu.imageUrl) {
          this.fileList = [] // 清空 fileList，不显示缩略图
        }
      })
    },
    handleDelete(row) {
      this.$confirm(`删除数据，该项数据下的子项将同步删除，确认删除？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(function () {
          return delMenu(row.menuId)
        })
        .then(() => {
          this.getTableData()
          this.$message({ type: 'success', message: '删除菜单成功!' })
        })
        .catch(() => {})
    },
    // 提交表单
    async handleUserSubmit() {
      try {
        // 先进行表单验证
        await this.$refs.userEdit.validate()
        if (!this.userDialogData.orderNum) {
          this.userDialogData.orderNum = '9999'
        }
        // 准备要提交的数据
        const submitData = { ...this.userDialogData }
        console.log(submitData)

        let response
        if (this.userDialogType === '新增') {
          response = await addMenu(submitData)
          if (response.code !== 200) {
            this.$message.error(response.msg)
            return
          }
          this.$message.success('菜单新增成功！')
          console.log(submitData)
        } else if (this.userDialogType === '编辑') {
          console.log('编辑：', submitData)
          response = await updateMenu(submitData)
          if (response.code !== 200) {
            this.$message.error(response.msg)
            return
          }
          this.$message.success('菜单编辑成功！')
        }
        this.handleUserDialogClose()
        this.getTableData()
      } catch (error) {
        console.error(`${this.userDialogType}菜单失败:`, error)
        this.$message.error(`${this.userDialogType}菜单失败，请检查表单数据！`)
        console.log('提交的数据:', this.userDialogData)
      }
    },

    handleAuthSubmit() {},
    filterNode(value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    getTableData() {
      listMenu(this.queryParams).then((response) => {
        this.tableData = handleTree(response.data, 'menuId')
      })
    },
    handleTreeSelect(data, id, parentId, children) {
      const config = {
        id: id || 'id',
        parentId: parentId || 'parentId',
        childrenList: children || 'children'
      }

      const tree = []
      const childrenMap = {}
      const idSet = new Set() // 用于存储已处理的 ID

      // Step 1: 构建 childrenMap
      data.forEach((item) => {
        const parent = item[config.parentId]
        if (!childrenMap[parent]) {
          childrenMap[parent] = []
        }
        childrenMap[parent].push(item)
      })

      // Step 2: 构建树形结构
      data.forEach((item) => {
        const parent = item[config.parentId]
        // 如果是根节点，parentId为0或者null
        if (parent === 0 || parent == null) {
          if (!idSet.has(item[config.id])) {
            // 检查 ID 是否已存在
            tree.push(item)
            idSet.add(item[config.id]) // 添加到已处理的 ID 集合
          }
        }
      })

      // Step 3: 递归添加 children
      const addChildren = (node) => {
        const children = childrenMap[node[config.id]]
        if (children) {
          node[config.childrenList] = []
          children.forEach((child) => {
            if (!idSet.has(child[config.id])) {
              // 检查 ID 是否已存在
              node[config.childrenList].push(child)
              idSet.add(child[config.id]) // 添加到已处理的 ID 集合
              addChildren(child) // 递归处理子节点
            }
          })
        } else {
          // 如果没有 children，确保 childrenList 存在并为一个空数组
          node[config.childrenList] = node[config.childrenList] || []
        }
      }

      tree.forEach((node) => addChildren(node))

      // Step 4: 处理未在树中的子节点并将其添加到主类目下
      Object.keys(childrenMap).forEach((parentId) => {
        const parentChildren = childrenMap[parentId]
        const isParentInTree = tree.some((item) => item[config.id] === parentId)

        if (!isParentInTree) {
          parentChildren.forEach((child) => {
            if (!idSet.has(child[config.id])) {
              // 检查 ID 是否已存在
              const newNode = { ...child, [config.childrenList]: [] } // 新节点
              tree.push(newNode) // 将这些菜单添加到主类目下
              idSet.add(child[config.id]) // 添加到已处理的 ID 集合
            }
          })
        }
      })

      return tree
    },
    async fetchTreeselectOptions(belongSystem) {
      try {
        const response = await treeselect({ belongSystem })
        // console.log(JSON.stringify(response.data, null, 2))
        this.menuOptions = []
        const menu = { id: 0, label: '主类目', children: [] }
        menu.children = this.handleTreeSelect(response.data, 'id')

        this.menuOptions.push(menu)
      } catch (error) {
        console.error('Error fetching treeselect options:', error)
      }
    },
    // getTreeselect() {
    //   listMenu().then((response) => {
    //     this.menuOptions = []
    //     const menu = { menuId: 0, menuName: '主类目', children: [] }
    //     menu.children = handleTree(response.data, 'menuId')
    //     this.menuOptions.push(menu)
    //     console.log(this.menuOptions)
    //     // 更新 userDialogConfig 的 options
    //     // this.userDialogConfig = this.userDialogConfig.map((config) => {
    //     //   if (config.prop === 'parentId' && config.type === 'treeselect') {
    //     //     return { ...config, options: this.menuOptions }
    //     //   }
    //     //   return config
    //     // })
    //   })
    // },
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.id,
        label: node.label,
        children: node.children
      }
    },
    handleChange(file, fileList) {
      this.fileList = fileList
    },
    handleRemove(file) {
      this.fileList = this.fileList.filter((item) => item.uid !== file.uid) // 从列表中移除文件
      this.userDialogData.icon = ''
      this.userDialogData.imageUrl = ''
      console.log('Removed file:', file)
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url // 设置预览图片的 URL
      this.dialogVisible = true // 显示预览对话框
    },
    handleExceed(files, fileList) {
      // 超过文件限制时的处理
      this.$message.warning('只能上传一个文件')
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-dialog__body .container {
  padding: 20px 0;
  .el-form-item {
    padding: 0;
  }
}
.table-container {
  .header {
    padding: 20px;
  }
  .tabs {
  }

  .dialog-footer {
    display: flex;
    justify-content: right;
    .button {
      width: 100px;
    }
  }
  .roleTree {
    display: flex;
  }
  .m_96 {
    margin: 20px 0;
  }
  .title {
    margin-bottom: 20px;
    font-size: 15px;
    font-weight: 700;
  }
}

::v-deep .el-table thead {
  color: #404040;
  font-weight: 500;
}
::v-deep .el-table th,
.el-table tr {
  background-color: #fafafa !important;
}
::v-deep .el-upload--picture-card {
  width: 80px;
  height: 80px;
  line-height: 80px;
  // margin: 10px;
  // border: 1px solid #409eff;
  border-radius: 8px;
  // overflow: hidden;
  // transition: transform 0.2s;
}
::v-deep .el-upload-list--picture-card .el-upload-list__item {
  width: 80px;
  height: 80px;
}
::v-deep .el-form-item {
  display: flex;
  align-items: center;
  .el-form-item__label {
    text-align: right;
    padding: 0 10px;
    width: 90px;
    height: auto;
  }
  .el-select {
    width: 100%;
  }
  .el-range-separator {
    line-height: normal;
    display: flex;
    align-items: center;
  }
  .el-input__icon {
    line-height: normal;
  }
  .el-form-item__content {
    // padding-left: 20px;
    flex: 1;
  }
  .el-input--suffix .el-input__inner {
    width: 100%;
  }
  .vue-treeselect__placeholder,
  .vue-treeselect__single-value {
    line-height: 40px;
    padding-left: 10px;
  }
}
</style>
